package com.dragon.utilslibrary.network.http;


import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 * http请求
 *
 * @author king.liangjinshui
 */
public class HttpSend extends HttpBase {
    String TAG = "HttpSend";
    /**
     * 是否取消
     */
    private boolean isCancelled = false;

    /**
     * 中途取消
     */
    public void cancelled() {
        isCancelled = true;
    }

    /**
     * 请求
     *
     * @param request
     * @param listioner
     */
    public void send(@NonNull HttpRequest request, @NonNull HttpListioner<HttpRespose> listioner) {
        HttpMethod method = request.getHttpMethod();//请求方式 GET or POST
        String mUrl = request.getUrl();//请求地址
        String mData = request.getParems();//请求参数
        File file = request.getDownloadFile();//文件下载（地址）
        HttpRespose respose = new HttpRespose();//响应
        onStartThread(listioner);
        try {
            // 根据地址创建URL对象
            URL url = new URL(mUrl);
            // 根据URL对象打开链接
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            // 设置请求的方式
            urlConnection.setRequestMethod(method.name());
            if (method == HttpMethod.POST) {
//				urlConnection.setRequestMethod("POST");
                // setDoInput的默认值就是true
                urlConnection.setDoInput(true); // 发送POST请求必须设置允许输入
                urlConnection.setDoOutput(true); // 发送POST请求必须设置允许输出
            }

            //是否使用缓存
            urlConnection.setUseCaches(request.isUseCaches());
            // 设置请求的超时时间
            if (request.getTimeOut() != -1) {
                urlConnection.setReadTimeout(request.getTimeOut());
                urlConnection.setConnectTimeout(request.getTimeOut());
            } else {
                urlConnection.setReadTimeout(5000);
                urlConnection.setConnectTimeout(5000);
            }
            // 设置请求的头
            urlConnection.setRequestProperty("Connection", "keep-alive");
            // 设置请求的头
            urlConnection.setRequestProperty("Content-Type",
                    request.getContent_Type());
            // "text/json;charset=utf-8");
            if (!TextUtils.isEmpty(mData)) {
                // mData = URLEncoder.encode(mData, "UTF-8");
                // 设置请求的头
                urlConnection.setRequestProperty("Content-Length",
                        String.valueOf(mData.getBytes().length));
            }
            // 设置请求的头
            urlConnection
                    .setRequestProperty("User-Agent",
                            "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0");

            // 获取输出流
            if (!TextUtils.isEmpty(mData)) {
                OutputStream os = urlConnection.getOutputStream();
                os.write(mData.getBytes());
                os.flush();
            }
            int code = urlConnection.getResponseCode();
            respose.setResposeMap(getHttpResponseHeader(urlConnection));
            respose.setErroCode(code);
            if (code == 200) {
                // 获取响应的输入流对象
                InputStream is = urlConnection.getInputStream();
                // 创建字节输出流对象
                ByteArrayOutputStream baos = new ByteArrayOutputStream();

                // 定义读取的长度
                int len = 0;
                long fileLend = urlConnection.getContentLength();
                long pressLend = 0;
                // 定义缓冲区
                byte buffer[] = new byte[2 * 1024];
                // 按照缓冲区的大小，循环读取
                if (file == null) {
                    while ((len = is.read(buffer)) != -1) {
                        // 根据读取的长度写入到os对象中
                        baos.write(buffer, 0, len);
                    }
                } else {
                    FileOutputStream fout = new FileOutputStream(file);
                    // 文件下载
                    while ((len = is.read(buffer)) != -1 && !isCancelled) {
                        // 根据读取的长度写入到os对象中
                        fout.write(buffer, 0, len);
                        fout.flush();
                        pressLend = pressLend + len;
//						publishProgress(pressLend, fileLend);
                        onProgressThread(listioner, pressLend, fileLend);
                    }
                    fout.close();
                    respose.setPath(file.getPath());
                }
                // 释放资源
                is.close();
                baos.close();
                // 返回字符串
                if (file == null) {
                    String result = new String(baos.toByteArray());
                    respose.setJson(result);
                }
            } else {
                System.out.println("链接失败.........");
                Log.i(TAG, "send: code--->" + code);

                respose.setMsg("http erro");
            }
        } catch (ProtocolException e) {
            e.printStackTrace();
            respose.setE(e);
            Log.i(TAG, "send: ProtocolException [" + e + "]");
        } catch (IOException e) {
            e.printStackTrace();
            respose.setE(e);
            Log.i(TAG, "send: IOException [" + e + "]");
        } catch (Exception e) {
            Log.i(TAG, "send: Exception [" + e + "]");
        }
        onResposeThread(listioner, respose);
//		return respose;
    }

    // 获取响应头
    private HashMap<String, String> getHttpResponseHeader(HttpURLConnection http)
            throws UnsupportedEncodingException {
        HashMap<String, String> header = new LinkedHashMap<String, String>();
        for (int i = 0; ; i++) {
            String mine = http.getHeaderField(i);
            if (mine == null)
                break;
            header.put(http.getHeaderFieldKey(i), mine);
        }
        return header;
    }
}
